home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue39 / Clinic / AddItem2U2.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-07-16  |  5.9 KB  |  159 lines

  1. unit AddItem2U2;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils;
  7.  
  8. type
  9.   EShellError = class(Exception);
  10.  
  11. procedure CreateShortCut(const Folder, Description, Path, Arguments,
  12.   Directory, IconPath: String; IconIndex: Integer; ShowMin: Boolean);
  13.  
  14. implementation
  15.  
  16. {$ifdef Ver90} { Delphi 2.0x }
  17.   {$define DelphiLessThan3}
  18. {$endif}
  19. {$ifdef Ver93} { C++ Builder 1.0x }
  20.   {$define DelphiLessThan3}
  21. {$endif}
  22.  
  23. uses
  24. {$ifdef DelphiLessThan3}
  25.   Ole2,
  26. {$else}
  27.   ShlObj, ActiveX, ComObj,
  28. {$endif}
  29.   Windows, Forms, Dialogs, ShellAPI;
  30.  
  31. {$ifdef DelphiLessThan3}
  32. type
  33.   TSHItemID = packed record           { mkid }
  34.     cb: Word;                         { Size of the ID (including cb itself) }
  35.     abID: array[0..0] of Byte;        { The item ID (variable length) }
  36.   end;
  37.  
  38.   PItemIDList = ^TItemIDList;
  39.   TItemIDList = packed record
  40.     mkid: TSHItemID;
  41.   end;
  42.  
  43.   IShellLink = class(IUnknown)
  44.   public
  45.     function GetPath(pszFile: PChar;  cchMaxPath: Integer;  var pfd: TWin32FindData; fFlags: Integer): HResult;  virtual;  stdcall;  abstract;
  46.     function GetIDList(var ppidl: PItemIDList): HResult;  virtual;  stdcall;  abstract;
  47.     function SetIDList(var ppidl: PItemIDList): HResult;  virtual;  stdcall;  abstract;
  48.     function GetDescription(pszName: PChar;  cchMaxName: Integer): HResult; virtual;  stdcall;  abstract;
  49.     function SetDescription(pszName: PChar): HResult;  virtual;  stdcall;  abstract;
  50.     function GetWorkingDirectory(pszDir: PChar;  cchMaxPath: Integer): HResult;  virtual;  stdcall;  abstract;
  51.     function SetWorkingDirectory(pszDir: PChar): HResult;  virtual;  stdcall;  abstract;
  52.     function GetArguments(pszArgs: PChar;  cchMaxPath: Integer): HResult; virtual;  stdcall;  abstract;
  53.     function SetArguments(pszArgs: PChar): HResult;  virtual;  stdcall;  abstract;
  54.     function GetHotkey(var pwHotKey: Word): HResult;  virtual;  stdcall;  abstract;
  55.     function SetHotkey(pwHotKey: Word): HResult;  virtual;  stdcall;  abstract;
  56.     function GetShowCmd(var piShowCmd: Integer): HResult;  virtual;  stdcall;  abstract;
  57.     function SetShowCmd(piShowCmd: Integer): HResult;  virtual;  stdcall;  abstract;
  58.     function GetIconLocation(pszIconPath: PChar;  cchIconPath: Integer;  var piIcon: Integer): HResult; virtual;  stdcall;  abstract;
  59.     function SetIconLocation(pszIconPath: PChar;  piIcon: Integer): HResult; virtual;  stdcall;  abstract;
  60.     function SetRelativePath(pszPathRel: PChar;  dsReserved: Integer): HResult; virtual;  stdcall;  abstract;
  61.     function Resolve(fFlags: Integer): HResult;  virtual;  stdcall;  abstract;
  62.     function SetPath(pszFile: PChar): HResult;  virtual;  stdcall;  abstract;
  63.   end;
  64.  
  65. function SHGetSpecialFolderLocation(hwndOwner: HWND; nFolder: Integer;
  66.   var ppidl: PItemIDList): HResult; stdcall; external 'Shell32.Dll';
  67. function SHGetPathFromIDList(pidl: PItemIDList; pszPath: PChar): BOOL; stdcall; external 'Shell32.Dll';
  68. function SHGetMalloc(var ppMalloc: IMalloc): HResult; stdcall; external 'Shell32.Dll';
  69.  
  70. const
  71.   CLSID_ShellLink: TGUID = (
  72.     D1:$00021401; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  73.   IID_ShellLink: TGUID = (
  74.     D1:$000214EE; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  75.  
  76.   CSIDL_PROGRAMS = 2;
  77. {$endif}
  78.  
  79. function Succeeded(Res: HResult): Boolean;
  80. begin
  81.   Result := Res and $80000000 = 0;
  82. end;
  83.  
  84. procedure OleCheck(Result: HResult);
  85. var
  86.   S: string;
  87. begin
  88.   if not Succeeded(Result) then
  89.   begin
  90.     S := SysErrorMessage(Result);
  91.     if S = '' then
  92.       FmtStr(S, 'OLE error %.8x', [Result]);
  93.     raise EShellError(S)
  94.   end
  95. end;
  96.  
  97. function GetLocation(Folder: DWord): String;
  98. var
  99.   PIDList: PItemIDList;
  100.   Buf: array[0..MAX_PATH] of Char;
  101.   Malloc: IMalloc;
  102. begin
  103.   if SHGetSpecialFolderLocation(Application.Handle, Folder, PIDList) <> NOERROR then
  104.     raise EShellError.Create('Cannot find desktop folder');
  105.   if SHGetPathFromIDList(PIDList, Buf) then
  106.     Result := StrPas(Buf);
  107.   if (SHGetMalloc(Malloc) = NOERROR) then
  108.     Malloc.Free(PIDList)
  109. end;
  110.  
  111. procedure CreateShortCut(const Folder, Description, Path, Arguments,
  112.   Directory, IconPath: String; IconIndex: Integer; ShowMin: Boolean);
  113. var
  114.   ShellLink: IShellLink;
  115.   PersistFile: IPersistFile;
  116.   LinkFile: array [0..MAX_PATH] of WideChar;
  117.   FolderPath, ShortCutPath: String;
  118. const
  119.   ShowCmd: array[Boolean] of Integer = (sw_ShowNormal, sw_Minimize);
  120. begin
  121.   FolderPath := GetLocation(CSIDL_PROGRAMS) + '\' + Folder;
  122.   { Unlike MkDir, this doesn't raise an exception if it fails }
  123.   CreateDirectory(PChar(FolderPath), nil);
  124.   { To display the folder when creating shortcuts, uncomment this line }
  125.   { ShellExecute(Application.Handle, nil, PChar(FolderPath), nil, nil, sw_ShowNormal); }
  126.   {$ifdef DelphiLessThan3}
  127.   if CoInitialize(nil) > 0 then
  128.     try
  129.       OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IID_ShellLink, ShellLink));
  130.       OleCheck(ShellLink.QueryInterface(IID_IPersistFile, PersistFile));
  131.   {$else}
  132.       ShellLink := CreateComObject(CLSID_ShellLink) as IShellLink;
  133.       PersistFile := ShellLink as IPersistFile;
  134.   {$endif}
  135.       ShellLink.SetDescription(PChar(Description));
  136.       ShellLink.SetPath(PChar(Path));
  137.       ShellLink.SetArguments(PChar(Arguments));
  138.       ShellLink.SetWorkingDirectory(PChar(Directory));
  139.       ShellLink.SetIconLocation(PChar(IconPath), IconIndex);
  140.       ShellLink.SetShowCmd(ShowCmd[ShowMin]);
  141.  
  142.       ShortCutPath := FolderPath + '\' + Description;
  143.       if UpperCase(ExtractFileExt(ShortcutPath)) <> '.LNK' then
  144.         ShortCutPath := ShortCutPath + '.LNK';
  145.       { In Delphi 3, we could rewrite the following two statements as: }
  146.       { OleCheck(PersistFile.Save(PWideChar(WideString(ShortCutPath)), True)); }
  147.       StringToWideChar(ShortCutPath, LinkFile, SizeOf(LinkFile));
  148.       OleCheck(PersistFile.Save(LinkFile, True));
  149.     {$ifdef DelphiLessThan3}
  150.       PersistFile.Release;
  151.       ShellLink.Release;
  152.     finally
  153.       CoUninitialize;
  154.     end;
  155.     {$endif}
  156. end;
  157.  
  158. end.
  159.